package com.horsen.service.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.horsen.common.util.JwtInfo;
import com.horsen.common.util.JwtUtils;
import com.horsen.common.util.MD5;
import com.horsen.common.util.ResultCodeEnum;
import com.horsen.service.base.exception.HseduException;
import com.horsen.service.base.model.VO.WebMemberOrderVO;
import com.horsen.service.user.mapper.MemberMapper;
import com.horsen.service.user.model.DTO.LoginDTO;
import com.horsen.service.user.model.DTO.MemberQueryDTO;
import com.horsen.service.user.model.DTO.RegisterDTO;
import com.horsen.service.user.model.Member;
import com.horsen.service.user.service.MemberService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 会员表 服务实现类
 * </p>
 *
 * @author Horsen
 * @since 2021-05-10
 */
@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {

    /**
     * 新增一个会员(会员注册)
     *
     * @param registerDTO 会员注册对象
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void register(RegisterDTO registerDTO) {
        String name = registerDTO.getName();
        String password = registerDTO.getPassword();
        String phone = registerDTO.getPhone();
        String email = registerDTO.getEmail();
        if (StringUtils.isEmpty(name)
                || StringUtils.isEmpty(password)
                || StringUtils.isEmpty(phone)
                || StringUtils.isEmpty(email)) {
            throw new HseduException(ResultCodeEnum.PARAM_ERROR);
        }
        // 是否被注册
        LambdaQueryWrapper<Member> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Member::getPhone, phone);
        if (baseMapper.selectCount(queryWrapper) > 0) {
            throw new HseduException(ResultCodeEnum.REGISTER_PHONE_ERROR);
        }
        LambdaQueryWrapper<Member> queryWrapper2 = Wrappers.lambdaQuery();
        queryWrapper2.eq(Member::getEmail, email);
        if (baseMapper.selectCount(queryWrapper2) > 0) {
            throw new HseduException(ResultCodeEnum.REGISTER_EMAIL_ERROR);
        }
        // 注册
        Member member = new Member().setName(name)
                .setPassword(MD5.encrypt(password))
                .setPhone(phone)
                .setEmail(email);
        baseMapper.insert(member);
    }

    /**
     * 查询一个会员(会员登录)
     *
     * @param loginDTO 登录对象
     * @return JWTToken
     */
    @Override
    public String login(LoginDTO loginDTO) {
        String name = loginDTO.getUsername();
        String password = loginDTO.getPassword();

        // 校验参数
        if (StringUtils.isEmpty(name) || StringUtils.isEmpty(password)) {
            throw new HseduException(ResultCodeEnum.PARAM_ERROR);
        }
        // 校验密码
        LambdaQueryWrapper<Member> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Member::getName, name)
                .eq(Member::getPassword, MD5.encrypt(password));
        Member member = baseMapper.selectOne(queryWrapper);
        if (member == null) {
            throw new HseduException(ResultCodeEnum.LOGIN_PASSWORD_ERROR);
        }
        // 检验用户是否被禁用
        if (member.getDisabled()) {
            throw new HseduException(ResultCodeEnum.LOGIN_DISABLED_ERROR);
        }
        // 存入token
        JwtInfo jwtInfo = new JwtInfo();
        jwtInfo.setId(member.getId());
        jwtInfo.setName(member.getName());
        jwtInfo.setAvatar(member.getAvatar());
        return JwtUtils.getJwtToken(jwtInfo, 24 * 60 * 60 * 1000);
    }

    /**
     * 根据ID获取一个会员订单VO
     *
     * @param id 会员ID
     * @return 会员订单VO
     */
    @Override
    public WebMemberOrderVO getMemberOrder(String id) {
        Member member = baseMapper.selectById(id);
        WebMemberOrderVO webMemberOrderVO = new WebMemberOrderVO();
        BeanUtils.copyProperties(member, webMemberOrderVO);
        return webMemberOrderVO;
    }

    /**
     * 分页查询
     *
     * @param page           当前页码
     * @param limit          每页记录数
     * @param memberQueryDTO 会员查询DTO
     * @return IPage类实例
     */
    @Override
    public IPage<Member> pageSelect(Long page, Long limit, MemberQueryDTO memberQueryDTO) {
        // 创建条件构造器
        LambdaQueryWrapper<Member> queryWrapper = Wrappers.lambdaQuery();
        // 设置orderBy关键字
        queryWrapper.orderByDesc(Member::getGmtCreate);
        if (memberQueryDTO != null) {
            String name = memberQueryDTO.getName();
            String email = memberQueryDTO.getEmail();
            String phone = memberQueryDTO.getPhone();
            Integer sex = memberQueryDTO.getSex();
            Integer age = memberQueryDTO.getAge();
            Boolean disabled = memberQueryDTO.getDisabled();
            // 设置查询条件
            if (!StringUtils.isEmpty(name)) {
                queryWrapper.like(Member::getName, name);
            }
            if (!StringUtils.isEmpty(email)) {
                queryWrapper.like(Member::getEmail, email);
            }
            if (!StringUtils.isEmpty(phone)) {
                queryWrapper.like(Member::getPhone, phone);
            }
            if (sex != null) {
                queryWrapper.eq(Member::getSex, sex);
            }
            if (age != null) {
                queryWrapper.eq(Member::getAge, age);
            }
            if (disabled != null) {
                queryWrapper.eq(Member::getDisabled, disabled);
            }
        }
        return baseMapper.selectPage(new Page<>(page, limit), queryWrapper);
    }

    /**
     * 根据ID修改会员封禁状态
     *
     * @param id 会员ID
     * @return 修改前状态
     */
    @Override
    public Boolean updateById(String id) {
        Member member = baseMapper.selectById(id);
        Boolean disabled = member.getDisabled();
        member.setDisabled(!disabled);
        this.updateById(member);
        return disabled;
    }
}
